

export default class AxisLinePrimitive {

  /**
   * @param {Cartesian3[]} options.positions The positions of the polyline
   * @param {Color} options.color The color of the line
   * @param {Boolean} [options.show=true] Whether the primitive is visible
   * @param {Object} [options.id] An id for the primitive
   * @param {Boolean} [options.loop=false] True if the polyline should loop
   * @param {Boolean} [options.arrow=false] True if the arrow material should be used
   * @param {Boolean} [options.width] The width of the polyline
   * @param {Boolean} [options.depthFail=true] True if a depthfail material should be used
   */
  constructor(options = {}) {
    // 线是否显示
    this.show = Cesium.defaultValue(options.show, true)
    // 线的id
    this.id = options.id

    // 线的位置数组
    let positions = options.positions

    if (options.loop) {
      positions = positions.slice()
      positions.push(positions[0])
    }

    // 箭头线的方向
    let isArrow = Cesium.defaultValue(options.arrow, false)
    // 线的宽度
    this._width = options.width || 8
    // 箭头线颜色
    this._color = options.color || Cesium.Color.RED

    // 类似透明度 不太理解
    this._depthFailColor = this._color.withAlpha(.3)

    // 保存位置数组
    this._positions = positions
    // 保存箭头方向
    this._arrow = isArrow

    this._depthFail = Cesium.defaultValue(options.depthFail, true)

    // 图元对象
    this._primitive = undefined
    // 创建包围盒
    this._boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
    // 克隆包围盒
    this._transformedBoundingSphere = Cesium.BoundingSphere.clone(this._boundingSphere)
    // 线图元矩阵 （初始化 默认值）
    this._modelMatrix = Cesium.Matrix4.clone(Cesium.Matrix4.IDENTITY)
    // 自动更新   
    this._update = true
  }

  /**
   * 更新
   * @param {*} frameState 
   */
  update(frameState) {
    if (!this.show) { return }

    if (this._update) {
      this._update = false
      this._primitive = this._primitive && this._primitive.destroy()

      let geometry = new Cesium.PolylineGeometry({
        positions: this._positions,
        width: this._width,
        vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
        arcType: Cesium.ArcType.NONE
      })

      let appearance1 , appearance2

      if (this._arrow) {
        appearance1 = new Cesium.PolylineMaterialAppearance({
          material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
            color: this._color
          })
        })
        if (this._depthFail) {
          appearance2 = new Cesium.PolylineMaterialAppearance({
            material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
              color: this._depthFailColor
            })
          });
        }
      } else {
        appearance1 = new Cesium.PolylineColorAppearance({
          translucent: this._color.alpha !== 1.0
        });
        if (this._depthFail) {
          appearance2 = new Cesium.PolylineColorAppearance({
            translucent: this._depthFailColor.alpha !== 1.0
          });
        }
      }

      var modelMatrix = this._modelMatrix;
      this._primitive = new Cesium.Primitive({
        geometryInstances: new Cesium.GeometryInstance({
          geometry: geometry,
          attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(this._color),
            depthFailColor: Cesium.ColorGeometryInstanceAttribute.fromColor(this._depthFailColor)
          },
          id: this.id,
          modelMatrix: modelMatrix
        }),
        appearance: appearance1,
        depthFailAppearance: appearance2,
        asynchronous: false
      })
      this._transformedBoundingSphere = Cesium.BoundingSphere.transform(this._boundingSphere, modelMatrix, this._transformedBoundingSphere)
    }

    this._primitive.update(frameState)
  }

  /**
   * 是否销毁
   * @returns 
   */
  isDestroyed(){
    return false
  }

  /**
   * 销毁
   */
  destroy(){
    this._primitive = this._primitive && this._primitive.destroy()
    return Cesium.destroyObject(this)
  }

  get modelMatrix() {
    return this._modelMatrix
  }

  set modelMatrix(value) {
    this._modelMatrix = Cesium.Matrix4.clone(value, this._modelMatrix)
    this._update = true
  }

  get positions() {
    return this._positions
  }

  set positions(positions) {
    this._positions = positions
    this._update = true
  }

  get color() {
    return this._color
  }

  get width() {
    return this._width
  }

  get boundingVolume() {
    return this._boundingVolume
  }
}